
        
package com.mall.order.service;

import com.alicp.jetcache.AutoReleaseLock;
import com.alicp.jetcache.Cache;
import com.alicp.jetcache.RefreshPolicy;
import com.alicp.jetcache.anno.CacheType;
import com.alicp.jetcache.anno.Cached;
import com.alicp.jetcache.anno.CreateCache;
import com.ctg.mse.common.cache.RedisSingle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

/**
 * @Description: Redis相关用法
 * @Author: zhouzhao
 * @CreateTime: 2022/10/19 10:38:29
 */
@Service
public class RedisDemoService {

    private static final Logger LOGGER = LoggerFactory.getLogger(RedisDemoService.class);

    @Autowired
    private RedisSingle redisSingle;

    private static final String testKeyPrefix = "DemoCacheTest";

    /**
     * jetcache 注解缓存基本测试
     * 注解文档见 https://github.com/alibaba/jetcache/wiki/MethodCache_CN
     *
     * @param echo
     * @return
     */
    @Cached(name = testKeyPrefix, key = "#echo", expire = 600, cacheType = CacheType.REMOTE)
    public String testCacheEcho(String echo) {
        LOGGER.debug("testCacheEcho :%s", echo);
        return echo;
    }

    @CreateCache
    private Cache<String, String> testCache;

    /**
     * 如果要调用本类经过cache修饰的方法，需要经过代理，需要自己注入自己的调用
     */
    @Autowired
    private RedisDemoService redisDemoService;

    /**
     * 更多缓存操作API 见文档 https://github.com/alibaba/jetcache/wiki/AdvancedCacheAPI_CN
     */
    @PostConstruct
    public void initCache() {
        //设置缓存未命中的load方法
        testCache.config().setLoader(key -> {
            LOGGER.debug("testCache key :" + key + " need load");
            return "load:" + key;    //TODO 这里去加载未命中key的缓存值
        });
        //对一些key比较少，实时性要求不高，加载开销非常大的缓存场景，适合使用自动刷新
        RefreshPolicy policy = RefreshPolicy.newPolicy(1, TimeUnit.MINUTES)
                .stopRefreshAfterLastAccess(30, TimeUnit.MINUTES);
        testCache.config().setRefreshPolicy(policy);
    }

    public String testRedisEcho(String echo) {
        String value = redisSingle.get(testKeyPrefix + echo);
        LOGGER.debug("testRedisEcho :" + echo + ":" + value);
        //尝试获取远程redis的分布式锁，这里对分布式要求高，需要用ZK或者consul的
        try (AutoReleaseLock lock = testCache.tryLock(testKeyPrefix + echo, 100, TimeUnit.SECONDS)) {
            if (lock != null) {
                // do something
                LOGGER.info("get Lock,key:" + testKeyPrefix + echo);
            }
        }
        //这样testCacheEcho的注解缓存会生效
        redisDemoService.testCacheEcho(echo);
        return echo;
    }

}
